from itertools import permutations, product
from typing import List
import operator

def calc_24_points(nums: List[int]) -> List[str]:
    """
    Find all valid arithmetic expressions using exactly the four given numbers
    that evaluate to 24. The expressions can use addition, subtraction,
    multiplication, and division, along with parentheses.
    
    Args:
        nums: A list of four natural numbers between 1 and 13
        
    Returns:
        A list of strings representing valid arithmetic expressions that
        evaluate to 24
    """
    # Store all valid expressions
    valid_expressions = []
    
    # Define arithmetic operations
    operations = {
        '+': operator.add,
        '-': operator.sub,
        '*': operator.mul,
        '/': lambda x, y: x / y if y != 0 else float('inf')  # Avoid division by zero
    }
    
    # Define all possible ways to combine four numbers with parentheses
    # We'll consider all possible ways to group operations
    def evaluate(nums_order, ops):
        """
        Try all possible ways to parenthesize the expression and evaluate it
        
        Args:
            nums_order: The order of the four input numbers
            ops: The three operations to apply
            
        Returns:
            A tuple containing the expression string and its value
        """
        # Try all possible ways to parenthesize four numbers
        # For four numbers, there are 5 possible ways to parenthesize:
        # ((a op b) op c) op d
        # (a op (b op c)) op d
        # a op ((b op c) op d)
        # a op (b op (c op d))
        # (a op b) op (c op d)
        
        results = []
        a, b, c, d = nums_order
        op1, op2, op3 = ops
        
        # Case 1: ((a op b) op c) op d
        try:
            val1 = operations[op1](a, b)
            val2 = operations[op2](val1, c)
            val3 = operations[op3](val2, d)
            expr1 = f"(({a} {op1} {b}) {op2} {c}) {op3} {d}"
            results.append((expr1, val3))
        except:
            pass
        
        # Case 2: (a op (b op c)) op d
        try:
            val1 = operations[op2](b, c)
            val2 = operations[op1](a, val1)
            val3 = operations[op3](val2, d)
            expr2 = f"({a} {op1} ({b} {op2} {c})) {op3} {d}"
            results.append((expr2, val3))
        except:
            pass
        
        # Case 3: a op ((b op c) op d)
        try:
            val1 = operations[op2](b, c)
            val2 = operations[op3](val1, d)
            val3 = operations[op1](a, val2)
            expr3 = f"{a} {op1} (({b} {op2} {c}) {op3} {d})"
            results.append((expr3, val3))
        except:
            pass
        
        # Case 4: a op (b op (c op d))
        try:
            val1 = operations[op3](c, d)
            val2 = operations[op2](b, val1)
            val3 = operations[op1](a, val2)
            expr4 = f"{a} {op1} ({b} {op2} ({c} {op3} {d}))"
            results.append((expr4, val3))
        except:
            pass
        
        # Case 5: (a op b) op (c op d)
        try:
            val1 = operations[op1](a, b)
            val2 = operations[op3](c, d)
            val3 = operations[op2](val1, val2)
            expr5 = f"({a} {op1} {b}) {op2} ({c} {op3} {d})"
            results.append((expr5, val3))
        except:
            pass
        
        return results
    
    # Try all permutations of the input numbers
    for nums_perm in permutations(nums):
        # Try all possible combinations of operations
        for ops in product(operations.keys(), repeat=3):
            # Evaluate all possible expressions
            expressions = evaluate(nums_perm, ops)
            
            # Check if any of the expressions evaluates to 24 (within a small tolerance)
            for expr, value in expressions:
                if abs(value - 24) < 1e-10:  # Use small tolerance for floating point comparison
                    # Format the expression to ensure proper spacing
                    formatted_expr = expr.replace('+', ' + ').replace('-', ' - ').replace('*', ' * ').replace('/', ' / ')
                    formatted_expr = ' '.join(formatted_expr.split())  # Remove extra whitespace
                    if formatted_expr not in valid_expressions:
                        valid_expressions.append(formatted_expr)
    
    return valid_expressions

# Test the function
if __name__ == "__main__":
    test_nums = [7, 11, 3, 10]
    results = calc_24_points(test_nums)
    
    print(f"Found {len(results)} expressions that evaluate to 24:")
    for expr in results:
        try:
            # Evaluate the expression to verify
            result = eval(expr.replace(' ', ''))
            print(f"{expr} = {result}")
        except:
            print(f"{expr} = Error evaluating")